//
// Calc.cpp for 208ajust in /home/druart_p/Work/math/my-math-epi/208
//
// Made by pierrick druart
// Login   <druart_p@epitech.net>
//
// Started on  Thu May 24 09:10:29 2012 pierrick druart
// Last update Fri Jun  1 10:23:44 2012 pierrick druart
//

#include	"Calc.hh"

// Construtor & Destructor

Calc::Calc(const std::string & file)
{
  this->total = 0;
  getValueFromFile(file);
  print();
  moyenne();
  probabilite();
  tab();
  tab2();
}

Calc::~Calc() {}

// Get File Value

void		Calc::getValueFromFile(const std::string & file)
{
  std::string	line;
  const char	*test = file.c_str();
  std::ifstream myfile(test);

  if (myfile.is_open())
    {
      while (myfile.good())
	{
	  int		x = 0;
	  int		ox = 0;
	  getline(myfile, line);
	  std::stringstream	tmp(line);
	  tmp >> x;
	  tmp >> ox;
	  this->_x.push_back(x);
	  this->_ox.push_back(ox);
	}
      this->_x.pop_back();
      this->_ox.pop_back();
      myfile.close();
    }
}

// Function

void		Calc::print()
{
  std::list<int>::iterator	it;

  std::cout << "\tMath 208ajust" << std::endl << std::endl;
  std::cout << "x  |\t" ;
  for (it = this->_x.begin(); it != this->_x.end(); ++it)
    std::cout << *it << "\t|\t" ;
  std::cout << std::endl << "ox |\t";
  for (it = this->_ox.begin(); it != this->_ox.end(); ++it)
    {
      std::cout << *it << "\t|\t" ;
      this->total += *it;
    }
  std::cout << std::endl << std::endl;
}

// CALC

void		Calc::moyenne()
{
  std::list<int>::iterator	it;
  std::list<int>::iterator	it2;
  double	       		tmp = 0;

  it2 = this->_ox.begin();
  for (it = this->_x.begin(); it != this->_x.end(); ++it)
    {
      tmp += (*it) * (*it2);
      ++it2;
    }
  this->moye = tmp / this->total;
  std::cout << "Moyenne = " << this->moye << std::endl;
}

void		Calc::probabilite()
{
  this->proba = this->moye / this->total;
  std::cout << "Probabilie = " << this->proba << std::endl;
}

double          Calc::facto(int nb)
{
  double	fact = 0;

  if (nb <= 1)
    return (1);
  fact = nb * facto(nb - 1);
  return (fact);
}

double		Calc::Ckn(int k)
{
  double		res = 0;

  res = facto(this->total) / (facto(k) * (facto(this->total - k)));
  return (res);
}

double		Calc::Tx(double Ckn, int x)
{
  double	res = 0;

  res = this->total * Ckn * pow(this->proba, x) * pow((1 - this->proba), this->total - x);
  return (res);
}

void		Calc::tab()
{
  std::list<int>::iterator	it;
  std::list<double>::iterator	it2;
  double       	res = 0;
  double       	tmp = 0;

  for (int i = 0; i != 9; ++i)
    {
      tmp = Tx(Ckn(i), i);
      res += tmp;
      this->_tx.push_back(tmp);
    }
  this->_tx.push_back(100 - res);
  std::cout << std::endl << "x  |\t" ;
  for (it = this->_x.begin(); it != this->_x.end(); ++it)
    std::cout << *it << "\t|\t" ;
  std::cout << std::endl << "Ox |\t";
  for (it = this->_ox.begin(); it != this->_ox.end(); ++it)
    std::cout << *it << "\t|\t" ;
  std::cout << std::endl << "Tx |\t";
  for (it2 = this->_tx.begin(); it2 != this->_tx.end(); ++it2)
    std::cout << std::setprecision(3) << *it2 << "\t|\t" ;
  std::cout << std::endl << std::endl;
}

void		Calc::tab2()
{
  std::list<double>::iterator	it;
  std::list<int>::iterator	it2;
  std::list<double>	a;
  std::list<double>	b;
  std::list<double>	c;
  double       	tmp = 0;
  double       	res = 0;
  double       	tmp2 = 0;
  double       	res2 = 0;
  bool		first = true;
  int		i = 0;

  it2 = this->_ox.begin();
  for (it = this->_tx.begin(); it != this->_tx.end(); ++it)
    {
      if (i < 7)
	{
	  if ((int)*it < 8 && (tmp + (int)*it) < 8)
	    {
	      tmp += *it;
	      tmp2 += *it2;
	      first = false;
	    }
	  else if (first == true)
	    {
	      a.push_back(i);
	      b.push_back(*it2);
	      c.push_back(*it);
	    }
	  else
	    {
	      first = true;
	      a.push_back(i - 1);
	      a.push_back(i);
	      b.push_back(tmp2);
	      b.push_back(*it2);
	      c.push_back(tmp);
	      c.push_back(*it);
	      tmp = 0;
	      tmp2 = 0;
	    }
	}
      else
	{
	res += *it;
	res2 += *it2;
	}
      it2++;
      i++;
    }
  a.push_back(7);
  b.push_back(res2);
  c.push_back(res);
  std::cout << std::endl << "x  |\t" ;
  for (it = a.begin(); it != a.end(); ++it)
    std::cout << *it << "\t|\t" ;
  std::cout << std::endl << "Ox |\t";
  for (it = b.begin(); it != b.end(); ++it)
    std::cout << *it << "\t|\t" ;
  std::cout << std::endl << "Tx |\t";
  for (it = c.begin(); it != c.end(); ++it)
    std::cout << std::setprecision(3) << *it << "\t|\t" ;
  std::cout << std::endl << std::endl;
  Xcar(b, c);
}

void		Calc::Xcar(std::list<double> tx, std::list<double> ox)
{
  std::list<double>::iterator	it;
  std::list<double>::iterator	it2;
  double	res = 0;
  double       	tmp = 0;

  it2 = tx.begin();
  for (it = ox.begin(); it != ox.end(); ++it)
    {
      res += pow((*it - *it2), 2) / *it2;
      it2++;
    }
  std::cout << "X2 = " << res << "\t";

  if (res <= 0)
    std::cout << "X2 = 0 \t P = 100%" << std::endl;
  else if (res > 0 && res <= 1.610)
    std::cout << "0 < X2 <= 1.610 \t 100% > P >= 90%" << std::endl;
  else if (res > 1.610 && res <= 2.343)
    std::cout << "1.610 < X2 <= 2.343 \t 90% > P >= 80%" << std::endl;
  else if (res > 2.3434 && res <= 3.000)
    std::cout << "2.343 < X2 <= 3.000 \t 80% > P >= 70%" << std::endl;
  else if (res > 3.000 && res <= 4.351)
    std::cout << "3.000 < X2 <= 4.351 \t 70% > P >= 50%" << std::endl;
  else if (res > 4.351 && res <= 6.064)
    std::cout << "4.351 < X2 <= 6.064 \t 50% > P >= 30%" << std::endl;
  else if (res > 6.024 && res <= 7.289)
    std::cout << "6.024 < X2 <= 7.289 \t 30% > P >= 20%" << std::endl;
  else if (res > 7.289 && res <= 9.236)
    std::cout << "7.289 < X2 <= 9.236 \t 20% > P >= 10%" << std::endl;
  else if (res > 9.236 && res <= 11.070)
    std::cout << "9.236 < X2 <= 11.070 \t 10% > P >= 5%" << std::endl;
  else if (res > 11.070 && res <= 13.388)
    std::cout << "11.070 < X2 <= 13.388 \t 5% > P >= 2%" << std::endl;
  else if (res > 13.388 && res <= 15.086)
    std::cout << "13.388 < X2 <= 15.086 \t 2% > P >= 1%" << std::endl;
  else
    std::cout << "15.086 < X2 <= 1000 \t 1% > P >= 0%" << std::endl;
}
